// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/palette/tools/create_note_action.h"

#include "ash/public/cpp/note_taking_client.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/palette/palette_ids.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/event.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace {
NoteTakingClient* GetAvailableClient() {
  auto* client = NoteTakingClient::GetInstance();
  if (!client || !client->CanCreateNote())
    return nullptr;
  return client;
}
}  // namespace

CreateNoteAction::CreateNoteAction(Delegate* delegate)
    : CommonPaletteTool(delegate) {
  Shell::Get()->AddPreTargetHandler(this);
}

CreateNoteAction::~CreateNoteAction() {
  Shell::Get()->RemovePreTargetHandler(this);
}

PaletteGroup CreateNoteAction::GetGroup() const {
  return PaletteGroup::ACTION;
}

PaletteToolId CreateNoteAction::GetToolId() const {
  return PaletteToolId::CREATE_NOTE;
}

void CreateNoteAction::OnEnable() {
  CommonPaletteTool::OnEnable();

  auto* client = GetAvailableClient();
  if (client)
    client->CreateNote();

  delegate()->DisableTool(GetToolId());
  delegate()->HidePalette();
}

views::View* CreateNoteAction::CreateView() {
  if (!GetAvailableClient())
    return nullptr;

  if (!ShouldShowOnDisplay())
    return nullptr;

  return CreateDefaultView(
      l10n_util::GetStringUTF16(IDS_ASH_STYLUS_TOOLS_CREATE_NOTE_ACTION));
}

const gfx::VectorIcon& CreateNoteAction::GetPaletteIcon() const {
  return kPaletteActionCreateNoteIcon;
}

void CreateNoteAction::OnKeyEvent(ui::KeyEvent* event) {
  // Listen for events generated by a bluetooth button on the tail of a stylus.
  // This is different from a regular stylus button on a barrel. Regular barrel
  // buttons require proximity to the screen and add a flag to the touch event,
  // rather than generating a key event.
  //
  // The only events with the EF_IS_STYLUS_BUTTON flags will be generated by
  // special bluetooth buttons.
  if (!(event->flags() & ui::EF_IS_STYLUS_BUTTON))
    return;
  if (event->type() == ui::ET_KEY_PRESSED)
    OnEnable();

  // This event shouldn't be handled as a regular key event, so consume it.
  event->StopPropagation();
}

// Don't show the create note action on external displays. This
// avoids some corner cases that haven't been addressed yet.
bool CreateNoteAction::ShouldShowOnDisplay() {
  if (external_display_for_test_)
    return false;

  // Allow the unit tests to function normally without a window
  aura::Window* root = delegate()->GetWindow();
  if (root == nullptr)
    return true;

  const display::Display& display =
      display::Screen::GetScreen()->GetDisplayNearestWindow(root);
  return display.IsInternal();
}

}  // namespace ash
